import type { Map, MapBrowserEvent } from "ol";
import type { Coordinate } from "ol/coordinate";
import type { FeatureLike } from "ol/Feature";
import { Feature } from "ol";
import { GeoJSON } from "ol/format";
import { Point } from "ol/geom";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import { Circle as CircleStyle, Fill, Stroke, Style, Text } from "ol/style";
import { ref, toRaw } from "vue";
import { projection } from "./view";

// 打点相关变量
let markerSource: VectorSource | null = null; // 标记图层数据源
let markerLayer: VectorLayer<VectorSource> | null = null; // 标记图层
let map: Map | null = null; // 当前地图实例
let markerClickListener: ((evt: MapBrowserEvent) => void) | null = null; // 点击监听器

// vue页面更新状态
export const isMarking = ref<boolean>(false); // 是否正在打点模式
export const markers = ref<Array<{ id: string; coordinate: Coordinate; lonLat: [number, number] }>>([]); // 存储点位信息

/** 重置 */
const reset = (): void => {
    if (map && markerLayer) map.removeLayer(markerLayer);
    isMarking.value = false;
    markers.value = [];
    markerSource = null;
    markerLayer = null;
    markerClickListener = null;
    map = null;
};

/** 初始化标记图层 */
export const initMarker = (_map: Map): void => {
    reset();
    map = toRaw(_map);
    markerLayer = new VectorLayer({
        source: new VectorSource(),
        zIndex: 1001, // 确保标记图层在最上层
        style: createMarkerStyle,
    });
    markerSource = markerLayer.getSource();
    map.addLayer(markerLayer);
};

/** 创建标记样式 */
const createMarkerStyle = (feature: FeatureLike): Style => {
    // 坐标转换, 如果有
    // const coordinate = feature.getGeometry().getCoordinates();
    // const transform = getTransform(projection, "EPSG:4326");
    // const lonLat = transform(coordinate);

    const lonLat = (feature as any).getGeometry?.().getCoordinates();

    return new Style({
        image: new CircleStyle({
            radius: 8,
            fill: new Fill({
                color: "#007bff", // 蓝色
            }),
            stroke: new Stroke({
                color: "#ffffff",
                width: 2,
            }),
        }),
        text: new Text({
            text: `${lonLat[0].toFixed(6)}, ${lonLat[1].toFixed(6)}`,
            offsetY: -20,
            fill: new Fill({
                color: "#000000",
            }),
            stroke: new Stroke({
                color: "#ffffff",
                width: 2,
            }),
            font: "12px Arial",
            textAlign: "center",
            backgroundFill: new Fill({
                color: "rgba(255, 255, 255, 0.8)",
            }),
            padding: [2, 4, 2, 4],
        }),
    });
};

/** 开始打点模式 */
export const startMarking = (isSingle = true): void => {
    if (!map || !markerSource) {
        console.error("地图或标记数据源未初始化");
        return;
    }

    if (isSingle) clearMarkers(); // 单点打点模式下清除之前的标记

    isMarking.value = true;

    // 添加点击监听器
    markerClickListener = (evt) => {
        const coordinate = evt.coordinate;

        // 转换坐标到经纬度
        // const transform = getTransform(projection, "EPSG:4326");
        // const lonLat = transform(coordinate) as [number, number];

        const id = `marker_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
        // 添加到标记列表
        markers.value.push({
            id,
            coordinate,
            lonLat: [Number(coordinate[0].toFixed(6)), Number(coordinate[1].toFixed(6))],
        });
        addMarker(coordinate, id);
        if (isSingle) stopMarking(); // 单点打点模式下点击后自动停止打点
    };

    map.on("click", markerClickListener);

    // 改变光标样式
    map.getTargetElement().style.cursor = "crosshair";
};

/** 停止打点模式 */
export const stopMarking = (): void => {
    if (!map) return;

    isMarking.value = false;

    // 移除点击监听器
    if (markerClickListener) {
        map.un("click", markerClickListener);
        markerClickListener = null;
    }

    // 恢复光标样式
    map.getTargetElement().style.cursor = "";
};

/** 添加标记点 */
export const addMarker = (coordinate: Coordinate, id?: string): void => {
    if (!markerSource) return;

    id = id || `marker_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
    const point = new Point(coordinate);
    const feature = new Feature({
        geometry: point,
        id,
    });

    markerSource.addFeature(feature);
};

/** 删除指定标记 */
export const removeMarker = (id: string): void => {
    if (!markerSource) return;

    const features = markerSource.getFeatures();
    const feature = features.find(f => f.get("id") === id);

    if (feature) {
        markerSource.removeFeature(feature);
        markers.value = markers.value.filter(marker => marker.id !== id);
    }
};

/** 清除所有标记 */
export const clearMarkers = (): void => {
    if (!markerSource) return;

    markerSource.clear();
    markers.value = [];
};

/** 获取所有标记的经纬度 */
export const getAllMarkers = (): Array<{ id: string; longitude: number; latitude: number }> => {
    return markers.value.map(marker => ({
        id: marker.id,
        longitude: marker.lonLat[0],
        latitude: marker.lonLat[1],
    }));
};

/** 获取标记的GeoJSON */
export const getMarkersGeoJSON = (): string | null => {
    if (!markerSource || markerSource.getFeatures().length === 0) {
        return null;
    }

    const format = new GeoJSON();
    const features = markerSource.getFeatures();
    const geoJsonObject = format.writeFeaturesObject(features, {
        featureProjection: projection,
        dataProjection: "EPSG:4326",
    });

    return JSON.stringify(geoJsonObject);
};

/** 清理标记模块资源 */
export const destroyMarker = (): void => {
    stopMarking(); // 停止打点模式
    reset(); // 重置所有状态
};
